package io.xccit.proxy;

import io.xccit.pojo.Calculator;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 * @author Xccit
 * @Date 2023-01-29
 * @Description 动态代理工厂类
 */
public class ProxyFactory {
    /**
     * 目标对象
     */
    private Object target;
    public ProxyFactory(Object target) {
        this.target = target;
    }

    /**
     *  ClassLoader loader:动态生成代理类的类加载器
     *  Class<?>[] interfaces:目标对象所实现的所有接口的Class对象数组
     *  InvocationHandler h:重写代理类中抽象方法的对象
     * @return 获取代理对象
     */
    public Object getProxy() {
        ClassLoader classLoader = this.getClass().getClassLoader();
        Class<?>[] interfaces = target.getClass().getInterfaces();
        InvocationHandler h = new InvocationHandler() {
            /**
             * proxy:代理对象
             * method:执行的方法
             * args:执行的方法的参数列表
             * @return
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //执行方法核心代码前日志打印
                System.out.println(method.getName()+",参数:"+ Arrays.toString(args));
                //执行的方法在代理类中执行时调用target(被代理类)中的同方法,获取args(参数)
                Object result = null;
                try {
                    result = method.invoke(target, args);
                    //执行方法核心代码后日志打印
                    System.out.println(method.getName()+",结果:"+ result);
                } catch (Exception e) {
                    System.out.println(method.getName()+"方法出现异常:"+e);
                } finally {
                    System.out.println(method.getName()+"方法执行完毕!");
                }
                return result;
            }
        };
        //调用Proxy类的newProxyInstance(),将所有参数返回
        return Proxy.newProxyInstance(classLoader,interfaces,h);
    }
}
